#include "bmp.h"
#include "lcd.h"
#include "Chess/Board.h"
#include "Chess/solider.h"
#include "Chess/gun.h"
#include "Chess/horse.h"
#include "Chess/rook.h"
#include "Chess/elephant.h"
#include "Chess/advisor.h"
#include "Chess/general.h"
#include "face.h"
#include <iostream>
using namespace std;

Board::Board() : lcd(nullptr)
{
}

void Board::init_piece(Lcd *lcd_instance)
{
    this->lcd = lcd_instance; // 保存lcd实例
    role = 0;
    PieceType initialBoard[9][10] = {
        {PieceType::Rche1, PieceType::kong, PieceType::kong, PieceType::Rzu1, PieceType::kong, PieceType::kong, PieceType::Bzu1, PieceType::kong, PieceType::kong, PieceType::Bche1},
        {PieceType::Rma1, PieceType::kong, PieceType::Rpao1, PieceType::kong, PieceType::kong, PieceType::kong, PieceType::kong, PieceType::Bpao1, PieceType::kong, PieceType::Bma1},
        {PieceType::Rxiang1, PieceType::kong, PieceType::kong, PieceType::Rzu2, PieceType::kong, PieceType::kong, PieceType::Bzu2, PieceType::kong, PieceType::kong, PieceType::Bxiang1},
        {PieceType::Rshi1, PieceType::kong, PieceType::kong, PieceType::kong, PieceType::kong, PieceType::kong, PieceType::kong, PieceType::kong, PieceType::kong, PieceType::Bshi1},
        {PieceType::Rshuai, PieceType::kong, PieceType::kong, PieceType::Rzu3, PieceType::kong, PieceType::kong, PieceType::Bzu3, PieceType::kong, PieceType::kong, PieceType::Bjiang},
        {PieceType::Rshi2, PieceType::kong, PieceType::kong, PieceType::kong, PieceType::kong, PieceType::kong, PieceType::kong, PieceType::kong, PieceType::kong, PieceType::Bshi2},
        {PieceType::Rxiang2, PieceType::kong, PieceType::kong, PieceType::Rzu4, PieceType::kong, PieceType::kong, PieceType::Bzu4, PieceType::kong, PieceType::kong, PieceType::Bxiang2},
        {PieceType::Rma2, PieceType::kong, PieceType::Rpao2, PieceType::kong, PieceType::kong, PieceType::kong, PieceType::kong, PieceType::Bpao2, PieceType::kong, PieceType::Bma2},
        {PieceType::Rche2, PieceType::kong, PieceType::kong, PieceType::Rzu5, PieceType::kong, PieceType::kong, PieceType::Bzu5, PieceType::kong, PieceType::kong, PieceType::Bche2}};

    // 初始化棋盘
    for (int i = 0; i < 9; i++)
    {
        for (int j = 0; j < 10; j++)
        {
            this->board[i][j] = initialBoard[i][j];
        }
    }

    // 创建棋子对象
    for (int i = 0; i < 9; i++) // 9行
    {
        for (int j = 0; j < 10; j++) // 10列
        {
            if (board[i][j] != PieceType::kong)
            {
                // 根据棋子类型创建相应的对象
                switch (board[i][j])
                {
                case PieceType::Rzu1:
                case PieceType::Rzu2:
                case PieceType::Rzu3:
                case PieceType::Rzu4:
                case PieceType::Rzu5:
                    pieces.push_back(make_unique<Soldier>(board[i][j], i, j, true));
                    break;
                case PieceType::Bzu1:
                case PieceType::Bzu2:
                case PieceType::Bzu3:
                case PieceType::Bzu4:
                case PieceType::Bzu5:
                    pieces.push_back(make_unique<Soldier>(board[i][j], i, j, false));
                    break;
                case PieceType::Rpao1:
                case PieceType::Rpao2:
                    pieces.push_back(make_unique<Gun>(board[i][j], i, j, true));
                    break;
                case PieceType::Bpao1:
                case PieceType::Bpao2:
                    pieces.push_back(make_unique<Gun>(board[i][j], i, j, false));
                    break;
                case PieceType::Rma1:
                case PieceType::Rma2:
                    pieces.push_back(make_unique<Horse>(board[i][j], i, j, true));
                    break;
                case PieceType::Bma1:
                case PieceType::Bma2:
                    pieces.push_back(make_unique<Horse>(board[i][j], i, j, false));
                    break;
                case PieceType::Rche1:
                case PieceType::Rche2:
                    pieces.push_back(make_unique<Rook>(board[i][j], i, j, true));
                    break;
                case PieceType::Bche1:
                case PieceType::Bche2:
                    pieces.push_back(make_unique<Rook>(board[i][j], i, j, false));
                    break;
                case PieceType::Rxiang1:
                case PieceType::Rxiang2:
                    pieces.push_back(make_unique<Elephant>(board[i][j], i, j, true));
                    break;
                case PieceType::Bxiang1:
                case PieceType::Bxiang2:
                    pieces.push_back(make_unique<Elephant>(board[i][j], i, j, false));
                    break;
                case PieceType::Rshi1:
                case PieceType::Rshi2:
                    pieces.push_back(make_unique<Advisor>(board[i][j], i, j, true));
                    break;
                case PieceType::Bshi1:
                case PieceType::Bshi2:
                    pieces.push_back(make_unique<Advisor>(board[i][j], i, j, false));
                    break;
                case PieceType::Rshuai:
                    pieces.push_back(make_unique<General>(board[i][j], i, j, true));
                    break;
                case PieceType::Bjiang:
                    pieces.push_back(make_unique<General>(board[i][j], i, j, false));
                    break;
                default:
                    break;
                }
            }
        }
    }
}

Piece *Board::get_piece_at(int x, int y)
{
    int row = y / 52;
    int col = x / 82;

    for (auto &piece : pieces)
    {
        auto pos = piece->get_position();
        if (pos.first == row && pos.second == col)
        {
            return piece.get();
        }
    }
    return nullptr;
}

void Board::show_piece()
{
    if (!lcd)
    {
        cout << "LCD not initialized" << endl;
        return;
    }

    // 清除棋盘上的所有棋子区域
    BMP chessboard("./res/chessboard.bmp");
    chessboard.show(lcd->addr());

    // 显示所有棋子
    for (const auto &piece : pieces)
    {
        PieceType type = piece->get_type();
        int row = piece->get_position().first;
        int col = piece->get_position().second;

        // 计算棋子在屏幕上的坐标
        int x = 5 + col * 82;
        int y = 10 + row * 52;

        // 根据棋子类型加载不同的图片
        string image_path = "";

        // 这里可以根据棋子类型选择不同图片
        switch (type)
        {
        case PieceType::kong:
            image_path = "./res/kong.bmp";
            break;
        case PieceType::Bche1:
        case PieceType::Bche2:
            image_path = "./res/che_1.bmp";
            break;
        case PieceType::Bma1:
        case PieceType::Bma2:
            image_path = "./res/ma_1.bmp";
            break;
        case PieceType::Bpao1:
        case PieceType::Bpao2:
            image_path = "./res/pao_1.bmp";
            break;
        case PieceType::Bshi1:
        case PieceType::Bshi2:
            image_path = "./res/shi_1.bmp";
            break;
        case PieceType::Bxiang1:
        case PieceType::Bxiang2:
            image_path = "./res/xiang_1.bmp";
            break;
        case PieceType::Bzu1:
        case PieceType::Bzu2:
        case PieceType::Bzu3:
        case PieceType::Bzu4:
        case PieceType::Bzu5:
            image_path = "./res/zu_1.bmp";
            break;
        case PieceType::Bjiang:
            image_path = "./res/jiang.bmp";
            break;
        case PieceType::Rche1:
        case PieceType::Rche2:
            image_path = "./res/che.bmp";
            break;
        case PieceType::Rma1:
        case PieceType::Rma2:
            image_path = "./res/ma.bmp";
            break;
        case PieceType::Rpao1:
        case PieceType::Rpao2:
            image_path = "./res/pao.bmp";
            break;
        case PieceType::Rshi1:
        case PieceType::Rshi2:
            image_path = "./res/shi.bmp";
            break;
        case PieceType::Rxiang1:
        case PieceType::Rxiang2:
            image_path = "./res/xiang.bmp";
            break;
        case PieceType::Rzu1:
        case PieceType::Rzu2:
        case PieceType::Rzu3:
        case PieceType::Rzu4:
        case PieceType::Rzu5:
            image_path = "./res/zu.bmp";
            break;
        case PieceType::Rshuai:
            image_path = "./res/shuai.bmp";
        default:
            break;
        }

        BMP piece_image(image_path.c_str());
        piece_image.show(lcd->addr(), x, y);
    }
}

bool Board::is_in_palace(int to_x, int to_y)
{
    // 获取移动到的位置
    int to_row = to_y / 52;
    int to_col = to_x / 82;

    if (to_row >= 0 && to_row < 9 && to_col >= 0 && to_col < 10)
    {
        return true;
    }
    return false;
}

int Board::move(int x, int y, int to_x, int to_y)
{
    // 获取点击的棋子位置
    int row = y / 52;
    int col = x / 82;

    // 获取移动到的位置
    int to_row = to_y / 52;
    int to_col = to_x / 82;

    // 判断是否是合法的移动
    if (!is_in_palace(to_x, to_y))
    {
        return 0;
    }
    
    // 获取要移动的棋子类型
    Piece *piece = get_piece_at(x, y);
    if (!piece)
    {
        cout << "No piece selected!" << endl;
        return 0;
    }
    
    // 判断先手顺序
    bool is_red = piece->get_is_red();
    if (role == 0)
    {
        if (!is_red)
        {
            showExampleText("请选择红方棋子！");
            return 0;
        }
    }
    else
    {
        if (is_red)
        {
            showExampleText("请选择黑方棋子！");
            return 0;
        }
    }

    // 棋子的移动规则
    if (!piece->is_valid_move(to_row, to_col, board))
    {
        showExampleText("无效移动！");
        return 0;
    }
    
    // 判断是否是同一方
    PieceType src_type = board[row][col];
    PieceType des_type = board[to_row][to_col];

    int src_value = static_cast<int>(src_type);
    int des_value = static_cast<int>(des_type);

    if (src_value >= 1 && src_value <= 16)
    {
        if (des_value <= 16 && des_value >= 1)
        {
            return 0;
        }
    }
    else if (src_value >= 17 && src_value <= 32)
    {
        if (des_value >= 17 && des_value <= 32)
        {
            return 0;
        }
    }

    // 吃掉棋子
    if (des_type != PieceType::kong)
    {
        auto it = pieces.begin();
        while (it != pieces.end())
        {
            auto pos = it->get()->get_position();
            if (pos.first == to_row && pos.second == to_col)
            {
                it = pieces.erase(it); // 移除被吃的棋子
                break;
            }
            else
            {
                ++it;
            }
        }
    }

    // 移动棋子
    board[to_row][to_col] = board[row][col];
    board[row][col] = PieceType::kong;

    // 更新棋子位置
    piece->set_position(to_row, to_col);

    show_piece();
    role = !role;

    return check_win_condition();
}

int Board::check_win_condition()
{
    // 检查是否还有将/帅存在
    bool red_general_exists = false;
    bool black_general_exists = false;

    for (const auto &piece : pieces)
    {
        if (piece->get_type() == PieceType::Rshuai)
        {
            red_general_exists = true;
        }
        if (piece->get_type() == PieceType::Bjiang)
        {
            black_general_exists = true;
        }
    }

    
    if (!red_general_exists)
    {
        showExampleText("黑方获胜！");
        usleep(500000);
        return 1; 
    }
    else if (!black_general_exists)
    {
        showExampleText("红方获胜！");
        usleep(500000);
        return 2;
    }
    
    return 0;
}

void Board::replay()
{
    // 清空棋盘数据
    for (int i = 0; i < 9; i++)
    {
        for (int j = 0; j < 10; j++)
        {
            board[i][j] = PieceType::kong;
        }
    }
    pieces.clear();
    Lcd::instance()->init();
    init_piece(Lcd::instance());
    show_piece();
    role = 0;
}

PieceType Board::get_board_piece(int row, int col) const
{
    if (row >= 0 && row < 9 && col >= 0 && col < 10) {
        return board[row][col];
    }
    return PieceType::kong;
}

const vector<unique_ptr<Piece>>& Board::get_pieces() const
{
    return pieces;
}

int Board::get_current_role() const
{
    return role;
}

void Board::set_current_role(int r)
{
    role = r;
}

Lcd* Board::get_lcd() const
{
    return lcd;
}

pair<int, int> Board::get_screen_position(int row, int col) const
{
    // 计算棋子在屏幕上的坐标
    int x = 5 + col * 82;
    int y = 10 + row * 52;
    return make_pair(x, y);
}

bool Board::has_piece(int row, int col) const
{
    if (row >= 0 && row < 9 && col >= 0 && col < 10) {
        return board[row][col] != PieceType::kong;
    }
    return false;
}

bool Board::is_red_piece(int row, int col) const
{
    if (!has_piece(row, col)) {
        return false;
    }
    
    PieceType type = board[row][col];
    int value = static_cast<int>(type);
    return (value >= 1 && value <= 16);
}

void Board::clone_board_state(PieceType dest[9][10]) const
{
    for (int i = 0; i < 9; i++) {
        for (int j = 0; j < 10; j++) {
            dest[i][j] = board[i][j];
        }
    }
}

void Board::clone_pieces_state(vector<unique_ptr<Piece>>& dest) const
{
    dest.clear();
    for (const auto& piece : pieces) {
        dest.push_back(clone_piece(piece.get()));
    }
}

void Board::apply_board_state(PieceType src[9][10])
{
    for (int i = 0; i < 9; i++) {
        for (int j = 0; j < 10; j++) {
            board[i][j] = src[i][j];
        }
    }
}

void Board::apply_pieces_state(vector<unique_ptr<Piece>>& src)
{
    pieces.clear();
    for (const auto& piece : src) {
        pieces.push_back(clone_piece(piece.get()));
    }
}

unique_ptr<Piece> Board::clone_piece(const Piece* piece) const
{
    if (!piece) return nullptr;
    
    PieceType type = piece->get_type();
    auto position = piece->get_position();
    bool isRed = piece->get_is_red();
    
    switch (type) {
        case PieceType::Rzu1:
        case PieceType::Rzu2:
        case PieceType::Rzu3:
        case PieceType::Rzu4:
        case PieceType::Rzu5:
        case PieceType::Bzu1:
        case PieceType::Bzu2:
        case PieceType::Bzu3:
        case PieceType::Bzu4:
        case PieceType::Bzu5:
            return make_unique<Soldier>(type, position.first, position.second, isRed);
            
        case PieceType::Rpao1:
        case PieceType::Rpao2:
        case PieceType::Bpao1:
        case PieceType::Bpao2:
            return make_unique<Gun>(type, position.first, position.second, isRed);
            
        case PieceType::Rma1:
        case PieceType::Rma2:
        case PieceType::Bma1:
        case PieceType::Bma2:
            return make_unique<Horse>(type, position.first, position.second, isRed);
            
        case PieceType::Rche1:
        case PieceType::Rche2:
        case PieceType::Bche1:
        case PieceType::Bche2:
            return make_unique<Rook>(type, position.first, position.second, isRed);
            
        case PieceType::Rxiang1:
        case PieceType::Rxiang2:
        case PieceType::Bxiang1:
        case PieceType::Bxiang2:
            return make_unique<Elephant>(type, position.first, position.second, isRed);
            
        case PieceType::Rshi1:
        case PieceType::Rshi2:
        case PieceType::Bshi1:
        case PieceType::Bshi2:
            return make_unique<Advisor>(type, position.first, position.second, isRed);
            
        case PieceType::Rshuai:
        case PieceType::Bjiang:
            return make_unique<General>(type, position.first, position.second, isRed);
            
        default:
            return nullptr;
    }
}

bool Board::execute_move(int from_row, int from_col, int to_row, int to_col)
{
    // 检查坐标有效性
    if (from_row < 0 || from_row >= 9 || from_col < 0 || from_col >= 10 ||
        to_row < 0 || to_row >= 9 || to_col < 0 || to_col >= 10) {
        return false;
    }
    
    // 检查起始位置是否有棋子
    if (!has_piece(from_row, from_col)) {
        return false;
    }
    
    // 获取要移动的棋子
    Piece* piece = nullptr;
    for (auto& p : pieces) {
        auto pos = p->get_position();
        if (pos.first == from_row && pos.second == from_col) {
            piece = p.get();
            break;
        }
    }
    
    if (!piece) {
        return false;
    }
    
    // 检查移动是否符合规则
    if (!piece->is_valid_move(to_row, to_col, board)) {
        return false;
    }
    
    // 检查是否吃掉己方棋子
    PieceType target_piece = board[to_row][to_col];
    if (target_piece != PieceType::kong) {
        int target_value = static_cast<int>(target_piece);
        int piece_value = static_cast<int>(piece->get_type());
        
        // 红方棋子
        if (piece_value >= 1 && piece_value <= 16) {
            if (target_value >= 1 && target_value <= 16) {
                return false; // 不能吃掉己方棋子
            }
        }
        // 黑方棋子
        else if (piece_value >= 17 && piece_value <= 32) {
            if (target_value >= 17 && target_value <= 32) {
                return false; // 不能吃掉己方棋子
            }
        }
    }
    
    // 执行移动
    board[to_row][to_col] = board[from_row][from_col];
    board[from_row][from_col] = PieceType::kong;
    
    // 更新棋子位置
    piece->set_position(to_row, to_col);
    
    // 移除被吃掉的棋子
    if (target_piece != PieceType::kong) {
        auto it = pieces.begin();
        while (it != pieces.end()) {
            auto pos = it->get()->get_position();
            if (pos.first == to_row && pos.second == to_col && 
                it->get()->get_type() == target_piece) {
                it = pieces.erase(it);
                break;
            } else {
                ++it;
            }
        }
    }
      // 切换角色
    role = !role;
    return true;
}

void Board::undo_move(int from_row, int from_col, int to_row, int to_col, PieceType captured_piece)
{
    // 恢复移动的棋子
    board[from_row][from_col] = board[to_row][to_col];
    board[to_row][to_col] = captured_piece;
    
    // 恢复棋子位置
    for (auto& piece : pieces) {
        auto pos = piece->get_position();
        if (pos.first == to_row && pos.second == to_col) {
            piece->set_position(from_row, from_col);
            break;
        }
    }
    
    // 如果有被吃掉的棋子，恢复它
    if (captured_piece != PieceType::kong) {

    }
}
